The form's legend
is a notoriously difficult element to style with CSS. Browser
inconsistencies and positioning limitations make working with it an
exercise in frustration. Yet, if we're concerned about using
meaningful, well-structured page elements, the legend is an attractive,
if not visually appealing, choice for displaying a title in our form's<fieldset>.
Left with only HTML and CSS,
we're forced to compromise either semantic markup or flexible design
choices. However, we can change the HTML as the page loads, turning each<legend> into an<h3>
for people viewing the page, while machines reading the
page—and those without JavaScript available—still
see the<legend>. This can be done straightforwardly using jQuery's .replaceWith() method:
$(document).ready(function() {
$('legend').each(function(index) {
$(this).replaceWith('<h3>' + $(this).text() + '</h3>');
});
});
Notice here that we can't rely
on jQuery's implicit iteration. With each element we replace, we need
to insert that element's unique text contents. For this we rely on the .each() method, which allows us to target the particular text with $(this).
Now, when we apply a blue background and white text color to the<h3> in the stylesheet, the form's first fieldset looks like this:
An alternative approach that keeps the<legend> elements intact involves wrapping their contents with a<span> tag:
$(document).ready(function() {
$('legend').wrapInner('<span></span>');
});
Wrapping a<span> inside the<legend> has at least two advantages over replacing the<legend> with an<h3>: it retains the semantic meaning of the<legend>
for screen readers with JavaScript support and it requires less work on
the part of the script. The disadvantage is that it makes the heading
style a little harder to achieve. At the very least, we have to set the position property of both the<fieldset> and the<span>, as well as the padding-top of the<fieldset> and the width of the<span>:
fieldset {
position: relative;
padding-top: 1.5em;
}
legend span {
position: absolute;
width: 100%;
}
Whether we choose to replace the form's<legend> elements or insert a<span> into them, they are now sufficiently styled for our purposes; it's time to clean up the required field messages.